import os
import stat
import pwd
from typing import List, Dict, Union

from WebBackend.dataclass.Directory import hide_path, __path_is_safe__


async def list_directory_contents(p: str) -> List[Dict[str, Union[str, int]]]:
    """
    列出指定目录的内容，返回包含文件和目录信息的字典列表。

    参数:
        p (str): 要列出的目录路径

    返回:
        List[Dict]: 包含目录项的列表，每个项是一个字典，格式如下:
            {
                "type": "file" | "dir" | "parent",
                "owner": str,
                "path_name": str,
                "size": int (仅当 type 为 "file" 时存在)
            }
        列表的第一个元素总是上级目录（如果是根目录，则指向自身）
    """
    # 确保路径是绝对路径
    abs_path = os.path.abspath(p)

    # 获取父目录路径（如果是根目录，则父目录还是根目录）
    parent_path = os.path.dirname(abs_path)
    if parent_path == abs_path:  # 已经是根目录（如 '/' 或 'C:\\'）
        parent_path = abs_path

    # 准备结果列表，第一个元素总是上级目录
    result = [{
        "type": "parent",
        "owner": "",
        "path_name": parent_path,
        "size": "",

    }]

    try:
        # 遍历目录内容
        for entry in os.listdir(abs_path):
            entry_path = os.path.join(abs_path, entry)
            if not __path_is_safe__(entry_path):
                continue
            stat_info = os.stat(entry_path)
            # 获取 owner 用户名
            try:
                owner = pwd.getpwuid(stat_info.st_uid).pw_name
            except (AttributeError, KeyError):
                owner = str(stat_info.st_uid)  # 如果无法获取用户名，返回 UID
            # 判断是文件还是目录
            if stat.S_ISDIR(stat_info.st_mode):
                item = {
                    "type": "folder",
                    "owner": owner,
                    "path_name": entry,
                }
            else:
                item = {
                    "type": "file",
                    "owner": owner,
                    "path_name": entry,
                    "size": stat_info.st_size,
                }
            result.append(item)

    except (PermissionError, FileNotFoundError) as e:
        # 处理无法访问目录的情况
        print(f"Error accessing directory {abs_path}: {e}")
        return []  # 或根据需要抛出异常

    return result


